package com.pethospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pethospital.dto.ConversationVO;
import com.pethospital.dto.MessageDTO;
import com.pethospital.entity.Conversation;
import com.pethospital.entity.Message;
import com.pethospital.entity.Staff;
import com.pethospital.exception.BusinessException;
import com.pethospital.mapper.ConversationMapper;
import com.pethospital.mapper.MessageMapper;
import com.pethospital.mapper.StaffMapper;
import com.pethospital.service.ConsultService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 在线咨询服务实现类
 */
@Slf4j
@Service
public class ConsultServiceImpl implements ConsultService {

    @Resource
    private ConversationMapper conversationMapper;

    @Resource
    private MessageMapper messageMapper;
    
    @Resource
    private StaffMapper staffMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createConversation(Long userId, Long staffId) {
        // 检查是否已有进行中的会话
        LambdaQueryWrapper<Conversation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Conversation::getUserId, userId)
                    .eq(Conversation::getStaffId, staffId)
                    .eq(Conversation::getStatus, 0);
        Conversation existConversation = conversationMapper.selectOne(queryWrapper);
        if (existConversation != null) {
            return existConversation.getId();
        }

        // 创建新会话
        Conversation conversation = new Conversation();
        conversation.setUserId(userId);
        conversation.setStaffId(staffId);
        conversation.setStatus(0); // 进行中
        conversation.setCreateTime(LocalDateTime.now());
        conversation.setUpdateTime(LocalDateTime.now());
        conversationMapper.insert(conversation);
        return conversation.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void endConversation(Long conversationId, Long userId) {
        // 查询会话
        Conversation conversation = conversationMapper.selectById(conversationId);
        if (conversation == null) {
            throw new BusinessException("会话不存在");
        }

        // 验证权限
        if (!conversation.getUserId().equals(userId) && !conversation.getStaffId().equals(userId)) {
            throw new BusinessException("无权操作此会话");
        }

        // 更新会话状态
        conversation.setStatus(1); // 已结束
        conversation.setUpdateTime(LocalDateTime.now());
        conversationMapper.updateById(conversation);
    }

    @Override
    public List<ConversationVO> getUserConversations(Long userId) {
        // 1. 查询用户的会话列表
        LambdaQueryWrapper<Conversation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Conversation::getUserId, userId)
                    .orderByDesc(Conversation::getUpdateTime);
        List<Conversation> conversations = conversationMapper.selectList(queryWrapper);
        
        if (conversations.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 2. 获取所有会话涉及的医护人员ID
        List<Long> staffIds = conversations.stream()
                .map(Conversation::getStaffId)
                .distinct()
                .collect(Collectors.toList());
        
        // 3. 批量查询医护人员信息
        LambdaQueryWrapper<Staff> staffQueryWrapper = new LambdaQueryWrapper<>();
        staffQueryWrapper.in(Staff::getId, staffIds);
        List<Staff> staffList = staffMapper.selectList(staffQueryWrapper);
        
        // 将医护人员信息转为Map，方便后续使用
        Map<Long, Staff> staffMap = staffList.stream()
                .collect(Collectors.toMap(Staff::getId, staff -> staff));
        
        // 4. 获取所有会话ID
        List<Long> conversationIds = conversations.stream()
                .map(Conversation::getId)
                .collect(Collectors.toList());
        
        // 5. 批量查询每个会话的最后一条消息
        Map<Long, Message> lastMessageMap = getLastMessages(conversationIds);
        
        // 6. 批量查询每个会话的未读消息数量（只统计医护人员发送的消息）
        Map<Long, Integer> unreadCountMap = getUnreadMessageCounts(conversationIds, userId, 1);
        
        // 7. 组装数据
        return conversations.stream().map(conversation -> {
            ConversationVO vo = ConversationVO.fromEntity(conversation);
            
            // 设置医护人员信息
            Staff staff = staffMap.get(conversation.getStaffId());
            if (staff != null) {
                vo.setStaffName(staff.getName());
                vo.setStaffAvatar(staff.getAvatar());
            }
            
            // 设置最后一条消息
            Message lastMessage = lastMessageMap.get(conversation.getId());
            if (lastMessage != null) {
                // 根据消息类型设置显示内容
                if (lastMessage.getContentType() != null && lastMessage.getContentType() == 1) {
                    vo.setLastMessage("[图片]");
                } else {
                    vo.setLastMessage(lastMessage.getContent());
                }
            }
            
            // 设置未读消息数量
            Integer unreadCount = unreadCountMap.get(conversation.getId());
            vo.setUnreadCount(unreadCount != null ? unreadCount : 0);
            
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<ConversationVO> getStaffConversations(Long staffId) {
        // 1. 查询医护人员的会话列表
        LambdaQueryWrapper<Conversation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Conversation::getStaffId, staffId)
                    .orderByDesc(Conversation::getUpdateTime);
        List<Conversation> conversations = conversationMapper.selectList(queryWrapper);
        
        if (conversations.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 2. 获取所有会话ID
        List<Long> conversationIds = conversations.stream()
                .map(Conversation::getId)
                .collect(Collectors.toList());
        
        // 3. 批量查询每个会话的最后一条消息
        Map<Long, Message> lastMessageMap = getLastMessages(conversationIds);
        
        // 4. 批量查询每个会话的未读消息数量（只统计用户发送的消息）
        Map<Long, Integer> unreadCountMap = getUnreadMessageCounts(conversationIds, staffId, 0);
        
        // 5. 组装数据
        return conversations.stream().map(conversation -> {
            ConversationVO vo = ConversationVO.fromEntity(conversation);
            
            // 设置最后一条消息
            Message lastMessage = lastMessageMap.get(conversation.getId());
            if (lastMessage != null) {
                // 根据消息类型设置显示内容
                if (lastMessage.getContentType() != null && lastMessage.getContentType() == 1) {
                    vo.setLastMessage("[图片]");
                } else {
                    vo.setLastMessage(lastMessage.getContent());
                }
            }
            
            // 设置未读消息数量
            Integer unreadCount = unreadCountMap.get(conversation.getId());
            vo.setUnreadCount(unreadCount != null ? unreadCount : 0);
            
            return vo;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取一批会话的最后一条消息
     * @param conversationIds 会话ID列表
     * @return 会话ID -> 最后一条消息的映射
     */
    private Map<Long, Message> getLastMessages(List<Long> conversationIds) {
        if (conversationIds.isEmpty()) {
            return new HashMap<>();
        }
        
        // 对每个会话，查询最新的一条消息
        List<Message> lastMessages = new ArrayList<>();
        
        for (Long conversationId : conversationIds) {
            LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Message::getConversationId, conversationId)
                    .orderByDesc(Message::getCreateTime)
                    .last("LIMIT 1");
            Message message = messageMapper.selectOne(queryWrapper);
            if (message != null) {
                lastMessages.add(message);
            }
        }
        
        // 将结果映射为 conversationId -> Message
        return lastMessages.stream()
                .collect(Collectors.toMap(Message::getConversationId, msg -> msg));
    }
    
    /**
     * 获取会话未读消息数量，只统计指定发送者类型的消息
     * @param conversationIds 会话ID列表
     * @param receiverId 接收者ID
     * @param senderType 发送者类型（0-用户，1-医护人员）
     * @return 会话ID -> 未读消息数量的映射
     */
    private Map<Long, Integer> getUnreadMessageCounts(List<Long> conversationIds, Long receiverId, Integer senderType) {
        if (conversationIds.isEmpty()) {
            return new HashMap<>();
        }
        
        // 为每个会话查询未读消息数量
        Map<Long, Integer> result = new java.util.HashMap<>();
        
        for (Long conversationId : conversationIds) {
            LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Message::getConversationId, conversationId)
                    .eq(Message::getSenderType, senderType)  // 只统计特定类型发送者的消息
                    .eq(Message::getReadStatus, 0);  // 未读
            Long count = messageMapper.selectCount(queryWrapper);
            result.put(conversationId, count != null ? count.intValue() : 0);
        }
        
        return result;
    }

    @Override
    public Page<Message> getMessages(Long conversationId, Long userId, int page, int size) {
        // 查询会话
        Conversation conversation = conversationMapper.selectById(conversationId);
        if (conversation == null) {
            throw new BusinessException("会话不存在");
        }

        // 验证权限
        if (!conversation.getUserId().equals(userId) && !conversation.getStaffId().equals(userId)) {
            throw new BusinessException("无权查看此会话");
        }

        // 分页查询消息
        Page<Message> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Message::getConversationId, conversationId)
                    .orderByAsc(Message::getCreateTime);
        return messageMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void readMessages(Long conversationId, Long userId) {
        // 查询会话
        Conversation conversation = conversationMapper.selectById(conversationId);
        if (conversation == null) {
            throw new BusinessException("会话不存在");
        }

        // 验证权限
        if (!conversation.getUserId().equals(userId) && !conversation.getStaffId().equals(userId)) {
            throw new BusinessException("无权操作此会话");
        }

        // 用户为接收者，将医护人员发送的消息标记为已读
        // 医护人员为接收者，将用户发送的消息标记为已读
        int senderType = conversation.getUserId().equals(userId) ? 1 : 0;
        
        LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Message::getConversationId, conversationId)
                     .eq(Message::getSenderType, senderType)
                     .eq(Message::getReadStatus, 0)
                     .set(Message::getReadStatus, 1);
        messageMapper.update(null, updateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Message saveMessage(Long conversationId, MessageDTO messageDTO) {
        // 查询会话
        Conversation conversation = conversationMapper.selectById(conversationId);
        if (conversation == null) {
            throw new BusinessException("会话不存在");
        }

        // 检查会话是否已结束
        if (conversation.getStatus() != null && conversation.getStatus() == 1) {
            throw new BusinessException("会话已结束，不能发送消息");
        }

        // 验证权限
        Long senderId = messageDTO.getSenderId();
        int senderType = messageDTO.getSenderType();
        if ((senderType == 0 && !conversation.getUserId().equals(senderId)) ||
            (senderType == 1 && !conversation.getStaffId().equals(senderId))) {
            throw new BusinessException("无权在此会话中发送消息");
        }

        // 保存消息
        Message message = new Message();
        message.setConversationId(conversationId);
        message.setSenderType(senderType);
        message.setSenderId(senderId);
        message.setContent(messageDTO.getContent());
        message.setContentType(messageDTO.getContentType());
        message.setReadStatus(0); // 未读
        message.setCreateTime(LocalDateTime.now());
        messageMapper.insert(message);

        // 更新会话的更新时间
        conversation.setUpdateTime(LocalDateTime.now());
        conversationMapper.updateById(conversation);

        return message;
    }
} 